
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2011-2012 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
*******************************************************************************
*
* @file Lab_demo.c
*
* @author a13984
*
* @version 0.0.1
*
* @date Jul-15-2011
*
* @brief providing framework of test cases for MCU. 
*
*******************************************************************************/

#include "common.h"
#include "rtc.h"
#include "pit.h"
#include "irda.h"
#include "mma8451_test.h"
#include "Led.h"
#include "systick.h"
#include "sysinit.h"
/******************************************************************************
* Global variables
******************************************************************************/

/******************************************************************************
* Constants and macros
******************************************************************************/
enum
{
	DemoIdle = 0,
	DemoIrDa,
	DemoAccelerometer,
	DemoThermistor,
//	DemoSPICommunication,
	DemoRTC,
	DemoEnd,
}DEMO_STATE;

enum
{
	LED_Auto = 0,
	LED_Manual,
	LED_Rtc,
	LED_Idle,
}LED_ControlMode;

#define ASLIDER_DELAY_TIMER		50
/******************************************************************************
* Local types
******************************************************************************/

/******************************************************************************
* Local function prototypes
******************************************************************************/
void DemoProcessing( void );
void Pit0CallBack( void );

extern void UART_InitPrint(void);
/******************************************************************************
* Local variables
******************************************************************************/

uint8_t u8DemoState = DemoRTC;
uint8_t u8IrDaTestStatus = 0;
uint8_t u8LedControlMode = 0;
uint8_t u8CurrentDemoState;
volatile uint8_t u8DemoModeUpdatedDelay = 0;
volatile uint8_t u8IrDATestDelay = 0;
volatile uint16_t u16LedCycleCount = 0;
/******************************************************************************
* Local functions
******************************************************************************/
int main (void);
void RTC_Task(void);
/******************************************************************************
* Global functions
******************************************************************************/
#define TSI_RELEASE                 0x01
#define TSI_TOUCH                   0x02
#define OVER_TIME_COUNT             3
#define TSI_THRESHOLD               500
uint32_t u32BaseLine;
uint32_t u32DeltaValue;
uint32_t u32Currentvalue;
uint8_t u8TSI_Status;
uint8_t u8TSI_OverTimeCount;
/********************************************************************/
void TSI_GetBaseLine(void);
uint32_t TSI_Sample(uint8_t u8PadIndex, uint8_t u8Numbers);
void TSI_Detection( void );
void TSI_ReleaseCallback(void);
void TSI_TouchCallback(void);
/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: main
*
* @brief 
*        
* @param  none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
int main(void)
{
    RTC_ConfigType  sRTCConfig;
    RTC_ConfigType  *pRTCConfig = &sRTCConfig;   
    PIT_ConfigType  sPITConfig0;    
    PIT_ConfigType  *pPIT_Config0   =&sPITConfig0; 
    uint8_t u8IrDAResult;
    
    /* Perform processor initialization */
	  sysinit();
    printf("FRDM-KE04Z Demo Application\n");
     /* configure RTC to 1Hz interrupt frequency */
    pRTCConfig->u16ModuloValue = 9;                                      
    pRTCConfig->bInterruptEn   = RTC_INTERRUPT_ENABLE;     /* enable interrupt */
    pRTCConfig->bClockSource   = RTC_CLKSRC_1KHZ;          /*clock source is 1khz*/
    pRTCConfig->bClockPresaler = RTC_CLK_PRESCALER_100;    /*prescaler is 100*/
    
    RTC_SetCallback(RTC_Task);
	RTC_Init(pRTCConfig);
    
    /* initialize LED by FTM driving */
    LED_DriveByFtm();
    LED_RedControl(100,0);
    LED_GreenControl(100,0);
    
   // printf("FRDM-KE04Z Demo Application\n");
    
    
	/* initialize IIC and MMA8451 for accerometer test */
	AccelInit();
    
    /* initialize PIT for perodic timer - 10mS */
    pPIT_Config0->u32LoadValue      = 240000L;
    pPIT_Config0->bFreeze           = FALSE;    
    pPIT_Config0->bModuleDis        = FALSE;    /*!< enable PIT module */     
    pPIT_Config0->bInterruptEn      = TRUE;
    pPIT_Config0->bChainMode        = FALSE; 
    pPIT_Config0->bTimerEn          = TRUE;

    PIT_Init(PIT_CHANNEL0, pPIT_Config0);  
    PIT_SetCallback(PIT_CHANNEL0, Pit0CallBack);   

    u8LedControlMode = LED_Auto;
    
    /* LED blue and green cycle 10 time*/
    u16LedCycleCount = 0;
    LED_RedControl(50,50);
    LED_GreenControl(0,50);
    while( u16LedCycleCount < 50 );
    LED_GreenControl(50,50);
    while( u16LedCycleCount < 3*100 );
    LED_GreenControl(0,0);
    LED_RedControl(0,0);
    u8CurrentDemoState = u8DemoState;
    TSI_GetBaseLine();


   	for(;;) {	

   				if( !u8IrDATestDelay )
   				{
                    /* initialize Irda interface */
                    IrDA_Init();
                    u8IrDAResult = IrDA_Test();

                    /* restore to ~normal uart functional */
                    SIM->SOPT &= ~SIM_SOPT_RXDFE_MASK;
                    SIM->SOPT &= ~SIM_SOPT_TXDME_MASK;
                    /* initialize UART for printing */
                    UART_InitPrint();
                             
                    
                     if( u8IrDAResult == 0 )
	                 {
	                 	printf("IrDA test success!\n");
	                 }
                     else
                     {
                        // printf("IrDA test fail!\n");
                     }
	                 u8IrDATestDelay = 30;
                }

				AccelDemo();

				if( u8CurrentDemoState != u8DemoState )
				{
					printf("Slip or touch the Aslider!\n");
					u8CurrentDemoState = u8DemoState;
				}
            }
   // return 0;
}

/*****************************************************************************//*!
+FUNCTION----------------------------------------------------------------
* @function name: RTC_Task
*
* @brief callback routine of RTC driver which does what you want to do at 
*        every RTC period.
*        
* @param  none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
static uint32_t u32CurrentTime = 0;
void RTC_Task(void)
{
	
    u32CurrentTime ++;

    if( u8LedControlMode == LED_Rtc )
    {
	    if( u32CurrentTime & 0x01 )
	    {
	    	SET_LED_BLUE(100);
	    }
	    else
	    {
	    	SET_LED_BLUE(0);
	    }

	    if( (u32CurrentTime % 10) == 0 )
	    {
	    	SET_LED_GREEN(100);
	    }
	    else if( (u32CurrentTime % 5) == 0 )
	    {
	    	SET_LED_GREEN(0);
	    }

	}
}

void Pit0CallBack( void )
{
	if( u16TiltDelay )
	{
		u16TiltDelay--;
	}
    
	if( u8IrDATestDelay )
	{
		u8IrDATestDelay --;
	}

	/* LED control */
	if( u8LedControlMode == LED_Auto )
	{
		LED_CallBack();
        u16LedCycleCount++;
	}

	/* determine demo updated speed */
	if( u8DemoModeUpdatedDelay )
	{
		u8DemoModeUpdatedDelay --;
	}
    u16LedCycleCount ++;
    /* run TSS task to check slider */
    TSI_Detection();
    
}


uint32_t TSI_Sample(uint8_t u8PadIndex, uint8_t u8Numbers)
{
    uint8_t i;
    uint32_t u32SampleValue;
    u32SampleValue = 0;
    
    if(u8PadIndex == 0)
    {
        for(i=0;i<u8Numbers;i++)
        {
            GPIOA->PDDR |= (1 << 13);    
            GPIOA->PCOR |= (1 << 13);                 /*!< output 0, discharger first */
            systick_init();                           /*!< start the timer */
            GPIOA->PIDR &= ~(1 << 13);
            GPIOA->PDDR &= ~(1 << 13);                /*!< set as input */
            while(!(GPIOA->PDIR & (1 << 13)));        /*!< wait GPIO charged to 1 */
            systick_disable();                    /*!< stop the PIT timer */
            u32SampleValue += (0x00FFFFFF - SysTick->VAL);
        }
    }
    else
    {
        for(i=0;i<u8Numbers;i++)
        {
            GPIOA->PDDR |= (1 << 16);    
            GPIOA->PCOR |= (1 << 16);                 /*!< output 0, discharger first */
            systick_init();                           /*!< start the timer */
            GPIOA->PIDR &= ~(1 << 16);
            GPIOA->PDDR &= ~(1 << 16);                /*!< set as input */
            while(!(GPIOA->PDIR & (1 << 16)));        /*!< wait GPIO charged to 1 */
            systick_disable();                    /*!< stop the PIT timer */
            u32SampleValue += (0x00FFFFFF - SysTick->VAL);
        }
    }
    
    return u32SampleValue;
}
void TSI_Detection( void )
{
    u32Currentvalue = 0;
    u32Currentvalue += TSI_Sample(0,8);
    u32Currentvalue += TSI_Sample(1,8);
    
    if( u32Currentvalue > u32BaseLine )
    {
        u32DeltaValue = u32Currentvalue - u32BaseLine;
    }
    else
    {
        u32DeltaValue = 0;
    }
    
    if(u32DeltaValue > TSI_THRESHOLD)
    {
        if(u8TSI_Status == TSI_RELEASE)
        {
           u8TSI_OverTimeCount ++;
           if(u8TSI_OverTimeCount > OVER_TIME_COUNT)
           {
               u8TSI_OverTimeCount = 0;
               u8TSI_Status = TSI_TOUCH;
               TSI_TouchCallback();
           }
        }
    }
    else
    {
        if(u8TSI_Status == TSI_TOUCH)
        {
           u8TSI_OverTimeCount ++;
           if(u8TSI_OverTimeCount > OVER_TIME_COUNT)
           {
               u8TSI_OverTimeCount = 0;
               u8TSI_Status = TSI_RELEASE;
               TSI_ReleaseCallback();
           }
        }
    }
}

void TSI_GetBaseLine(void)
{
    uint8_t i;
    u32BaseLine = 0;
    for(i=0;i<16;i++)
    {
        u32BaseLine += TSI_Sample(0,8);
        u32BaseLine += TSI_Sample(1,8);
    }
    u32BaseLine = u32BaseLine/16;
    u8TSI_Status = TSI_RELEASE;
}

void TSI_TouchCallback(void)
{
    u8LedControlMode = LED_Auto;
    /* LED blue and green cycle 10 time*/
    LED_RedControl(50,50);
}

void TSI_ReleaseCallback(void)
{
    LED_RedControl(0,0);
}

